#pragma once
#include "../Comm/Comm.h"
#include "../ThreadCache/ThreadCache.h"
#include "../PageCache/PageCache.h"
#include "../ObjectPool/ObjectPool.h"

// static ObjectPool<ThreadCache> pool;//全局静态内存池
extern ObjectPool<ThreadCache> pool_for_thread;//cpp中定义一份实例,其余文件使用声明外部变量
static thread_local ThreadCache* pTLSThreadCache = nullptr;//TLS:thread local storage线程局部存储  推荐使用thread_local
static void* ConcurrentAlloc(size_t size)
{
	// 通过TLS 每个线程无锁的获取自己的专属的ThreadCache对象
	size_t n = NPAGES - 1;
	if(size > MAX_BYTES)
	{
		//同样需要对齐:直接通过page_cache,new span
		size_t alignSize = SizeClass::RoundUp(size);//按照页对齐,申请多少页:8KB
		size_t kPage = alignSize >> PAGE_SHIFT;
		PageCache::GetInstance()->GetMutex().lock();
		Span* span = PageCache::GetInstance()->NewSpan(kPage);
		PageCache::GetInstance()->GetMutex().unlock();
		void* ptr = (void*)((span->_pageId) << PAGE_SHIFT);
		return ptr;
	}

	else
	{
		if (pTLSThreadCache == nullptr)
		{
			// pTLSThreadCache = new ThreadCache;
			pTLSThreadCache = pool_for_thread.New();
		}

		return pTLSThreadCache->Allocate(size);
	}
}

static void ConcurrentFree(void* ptr)
{
	Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);
	size_t alignSize = span->_alignSize;
	if(alignSize > MAX_BYTES)
	{
		PageCache::GetInstance()->GetMutex().lock();	
		PageCache::GetInstance()->ReleaseToPage(span);//复用page_cache的逻辑
		PageCache::GetInstance()->GetMutex().unlock();	
	}
	else
	{
		assert(pTLSThreadCache);
		pTLSThreadCache->Deallocate(ptr, alignSize);
	}
}


static void ConcurrentSourcesFree()
{
	if(pTLSThreadCache)
    	pool_for_thread.Delete(pTLSThreadCache);
}